package g2.routemaster.gui.actions;

import g2.routemaster.gui.BoardSingleton;
import g2.routemaster.gui.GManager;
import g2.routemaster.gui.general.EBonus;
import g2.routemaster.gui.general.ECityCard;
import g2.routemaster.model.BlindStack;
import g2.routemaster.model.Board;
import g2.routemaster.model.BonusPile;
import g2.routemaster.model.BonusTile;
import g2.routemaster.model.Branch;
import g2.routemaster.model.City;
import g2.routemaster.model.CityCard;
import g2.routemaster.model.GameManager;
import g2.routemaster.model.Hand;
import g2.routemaster.model.LengthTile;
import g2.routemaster.model.OutsideOfBaiern;
import g2.routemaster.model.PlayedStack;
import g2.routemaster.model.Player;
import g2.routemaster.model.Region;
import g2.routemaster.model.RegionTile;
import g2.routemaster.model.Spielender;
import g2.routemaster.model.TurnManager;

import java.util.Iterator;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.ApplicationWindow;

public class TestAction extends Action {
   private ApplicationWindow window;
   public TestAction(ApplicationWindow window) {
      setText("Auto Flags@Ctrl+Alt+1");
      setToolTipText("Test Action");
      this.window = window;
   }
   
   public void run() {
      //situationBeforeScoring();
      //situationPlayLeftRight();
      //situationLastRound();
      //situationAllBonuses();
      //situation8CardsOnBoard();
      situationDemo();
      BoardSingleton.instance().updateAll();
   }
   
   void situationDemo(){
      GameManager gm = GManager.instance().getGameManager();
      Player playerKaia = gm.getFirstPlayer();
      Player playerMaie = gm.getNextPlayer(playerKaia);
      
      addFlag(gm, playerKaia, ECityCard.CARLSRUHE.nom());
      addFlag(gm, playerKaia, ECityCard.FREIBURG.nom());
      addFlag(gm, playerKaia, ECityCard.BASEL.nom());
      addFlag(gm, playerKaia, ECityCard.SIGMARINGEN.nom());
      addFlag(gm, playerKaia, ECityCard.STUTTGARD.nom());
      addFlag(gm, playerKaia, ECityCard.ULM.nom());
      addFlag(gm, playerKaia, ECityCard.KEMPTEN.nom());
      addFlag(gm, playerKaia, ECityCard.AUGSBURG.nom());
      addFlag(gm, playerKaia, ECityCard.INGOLSTADT.nom());
      addFlag(gm, playerKaia, ECityCard.NYRNBERG.nom());
      addFlag(gm, playerKaia, ECityCard.REGENSBURG.nom());
      addFlag(gm, playerKaia, ECityCard.PASSAU.nom());
      addFlag(gm, playerKaia, ECityCard.MYNCHEN.nom());
      addFlag(gm, playerKaia, ECityCard.INNSBRUCK.nom());
      addFlag(gm, playerKaia, ECityCard.SALZBURG.nom());
      addFlag(gm, playerKaia, ECityCard.BUDWEIS.nom());
      addFlag(gm, playerKaia, ECityCard.PILSEN.nom());

      addFlag(gm, playerMaie, ECityCard.CARLSRUHE.nom());
      addFlag(gm, playerMaie, ECityCard.STUTTGARD.nom());
      addFlag(gm, playerMaie, ECityCard.ULM.nom());
      addFlag(gm, playerMaie, ECityCard.SIGMARINGEN.nom());
      addFlag(gm, playerMaie, ECityCard.BASEL.nom());
      addFlag(gm, playerMaie, ECityCard.ZYRICH.nom());
      addFlag(gm, playerMaie, ECityCard.WYRZBURG.nom());
      addFlag(gm, playerMaie, ECityCard.INGOLSTADT.nom());
      addFlag(gm, playerMaie, ECityCard.AUGSBURG.nom());
      addFlag(gm, playerMaie, ECityCard.KEMPTEN.nom());
      addFlag(gm, playerMaie, ECityCard.INNSBRUCK.nom());
      addFlag(gm, playerMaie, ECityCard.MYNCHEN.nom());
      addFlag(gm, playerMaie, ECityCard.PASSAU.nom());
      addFlag(gm, playerMaie, ECityCard.REGENSBURG.nom());
      addFlag(gm, playerMaie, ECityCard.NYRNBERG.nom());
   }
   
   void addFlag(GameManager gm, Player player, String cityName){
      Branch branch = player.getFreeBranch();
      branch.setCity(getCity(gm, cityName));
   }
   
   void situationLastRound(){
      GameManager gm = GManager.instance().getGameManager();
      TurnManager tm = gm.getTurnManager();
      Player player = gm.getTurnManager().getPlayer();
      player.addToBonusTiles(getSpielende(gm));
      tm.registerDrawCard();
      tm.registerPlayCard();
      gm.nextTurn();
   }
   
   void situationAllBonuses(){
      GameManager gm = GManager.instance().getGameManager();
      Player player = gm.getTurnManager().getPlayer();
      player.addToBonusTiles(getLengthTile(5));
      player.addToBonusTiles(getLengthTile(6));
      player.addToBonusTiles(getLengthTile(7));
      player.addToBonusTiles(getRegionTile(EBonus.BADEN));
      player.addToBonusTiles(getRegionTile(EBonus.BAIERN));
      player.addToBonusTiles(getRegionTile(EBonus.BOHMEN_SALZBURG));
      player.addToBonusTiles(getOutsideBaiernTile());
      player.addToBonusTiles(getRegionTile(EBonus.SCHWEIZ_TYROL));
      player.addToBonusTiles(getRegionTile(EBonus.WYRTTEMBERG_HOHENZOLLERN));
   }
   
   void situationPlayLeftRight(){
      GameManager gm = GManager.instance().getGameManager();
      TurnManager tm = gm.getTurnManager();
      Player player = gm.getTurnManager().getPlayer();
      PlayedStack ps = player.getPlayedStack();
      ps.addToCityCard(getCard(gm, ECityCard.CARLSRUHE));

      Hand hand = player.getHand();
      hand.addToCityCard(getCard(gm, ECityCard.MANNHEIM));
      
      tm.registerDrawCard();
      tm.registerDrawCard();
   }

   void situationBeforeScoring(){
      GameManager gm = GManager.instance().getGameManager();
      TurnManager tm = gm.getTurnManager();
      tm.setOfficials(null);
      Player player = gm.getTurnManager().getPlayer();
      PlayedStack ps = player.getPlayedStack();
      ps.addToCityCard(getCard(gm, ECityCard.MANNHEIM));
      ps.addToCityCard(getCard(gm, ECityCard.CARLSRUHE));
      ps.addToCityCard(getCard(gm, ECityCard.FREIBURG));
      
      Hand hand = player.getHand();
      hand.addToCityCard(getCard(gm, ECityCard.STUTTGARD));
      hand.addToCityCard(getCard(gm, ECityCard.ULM));
      hand.addToCityCard(getCard(gm, ECityCard.SIGMARINGEN));
      hand.addToCityCard(getCard(gm, ECityCard.SIGMARINGEN));
      tm.registerDrawCard();
      tm.registerPlayCard();
   }
   
   void situation8CardsOnBoard(){
      GameManager gm = GManager.instance().getGameManager();
      TurnManager tm = gm.getTurnManager();
      tm.setOfficials(null);
      
      Player player = gm.getTurnManager().getPlayer();
      PlayedStack ps = player.getPlayedStack();
      ps.addToCityCard(getCard(gm, ECityCard.MANNHEIM));
      ps.addToCityCard(getCard(gm, ECityCard.WYRZBURG));
      ps.addToCityCard(getCard(gm, ECityCard.NYRNBERG));
      ps.addToCityCard(getCard(gm, ECityCard.REGENSBURG));
      ps.addToCityCard(getCard(gm, ECityCard.PASSAU));
      ps.addToCityCard(getCard(gm, ECityCard.LINZ));
      ps.addToCityCard(getCard(gm, ECityCard.BUDWEIS));
      //ps.addToCityCard(getCard(gm, ECityCard.PILSEN));

      Hand hand = player.getHand();
      hand.addToCityCard(getCard(gm, ECityCard.LODZ));

      tm.registerDrawCard();
      tm.registerPlayCard();
   }
   
   private CityCard getCard(GameManager gm, ECityCard eCard){
      BlindStack bs = gm.getBoard().getBlindStack();
      Iterator iter = bs.iteratorOfCityCard();
      while(iter.hasNext()){
         CityCard card = (CityCard)iter.next();
         if(card.getCity().getName().equals(eCard.nom())){
            return card;
         }
      }
      return null;
   }
   
   private City getCity(GameManager gm, String cityName){
      Iterator iterRegion = gm.getBoard().iteratorOfRegion();
      while(iterRegion.hasNext()){
         Region region = (Region)iterRegion.next();
         Iterator iterCity = region.iteratorOfCity();
         while(iterCity.hasNext()){
            City city = (City)iterCity.next();
            if(city.getName().equals(cityName)){
               return city;
            }
         }
      }
      return null;
   }
   
   private BonusTile getSpielende(GameManager gm){
      Board board = gm.getBoard();
      Iterator iterPile = board.iteratorOfBonusPile();
      while(iterPile.hasNext()){
         BonusPile pile = (BonusPile)iterPile.next();
         Iterator iterTile = pile.iteratorOfBonusTiles();
         while(iterTile.hasNext()){
            BonusTile tile = (BonusTile)iterTile.next();
            if(tile instanceof Spielender){
               return tile;
            }
         }
      }
      return null;
   }
   
   private BonusTile getLengthTile(int length){
      GameManager gm = GManager.instance().getGameManager();
      Board board = gm.getBoard();
      Iterator iterPile = board.iteratorOfBonusPile();
      while(iterPile.hasNext()){
         BonusPile pile = (BonusPile)iterPile.next();
         Iterator iterTile = pile.iteratorOfBonusTiles();
         while(iterTile.hasNext()){
            BonusTile tile = (BonusTile)iterTile.next();
            if(tile instanceof LengthTile
                  && ((LengthTile)tile).getLength() == length){
               return tile;
            }
         }
      }
      return null;
   }
   
   private BonusTile getRegionTile(EBonus name){
      GameManager gm = GManager.instance().getGameManager();
      Board board = gm.getBoard();
      Iterator iterPile = board.iteratorOfBonusPile();
      while(iterPile.hasNext()){
         BonusPile pile = (BonusPile)iterPile.next();
         Iterator iterTile = pile.iteratorOfBonusTiles();
         while(iterTile.hasNext()){
            BonusTile tile = (BonusTile)iterTile.next();
            if(tile instanceof RegionTile
                  && pile.getName().equals(name.nom())){
               return tile;
            }
         }
      }
      return null;      
   }

   private BonusTile getOutsideBaiernTile(){
      GameManager gm = GManager.instance().getGameManager();
      Board board = gm.getBoard();
      Iterator iterPile = board.iteratorOfBonusPile();
      while(iterPile.hasNext()){
         BonusPile pile = (BonusPile)iterPile.next();
         Iterator iterTile = pile.iteratorOfBonusTiles();
         while(iterTile.hasNext()){
            BonusTile tile = (BonusTile)iterTile.next();
            if(tile instanceof OutsideOfBaiern){
               return tile;
            }
         }
      }
      return null;
   }

}
